--[[
Copyright:www.vxinyou.com
Author:马柏威
CreateTime:2014-12-11
Description:活物对象类，封装了状态和基本的行动方法
]]
local clsLivingObject = Class("lua/game/clsGameObject.lua"):Inherit()

------------------------------public------------------------------
------------------------------------------------------------------
local attackMoveTime = 0.25 --攻击移动时间
local attackMoveDistance = 20--攻击移动距离
local lastAttackMoveTime = 0.3 --最后一击移动时间
local lastAttackMoveDistance = 200--最后一击移动距离

--Function:执行动作
function clsLivingObject:run(state, args)
	self.stateMachine:changeToTargetState(state, args)
end
--Function:结束当前动作
function clsLivingObject:endRun()
	self.stateMachine:endState()
end
--Function:清除对象状态
function clsLivingObject:clearState()
	self.skillActionManager:clearAllSkillAction()
	self:stopAllActions()
	--self:stopAllAnimate()
	self.timerManager:killAllTimer()
	self.stateMachine:clearState()
end
--Output:返回AI调用时间
function clsLivingObject:getAICallTime()
	return self.AICallTime
end
--Function:设置AI调用时间
function clsLivingObject:setAICallTime(fValue)
	self.AICallTime = fValue
end
--Function:是否能改变状态
function clsLivingObject:canChangeState(to)
	return self.stateMachine:canChangeState(self:getCurState(),to)
end
--Function:获得当前状态
function clsLivingObject:getCurState()
	return self.stateMachine:getNowState()
end
--Function:初始化状态机状态
function clsLivingObject:resetState()
	self.stateMachine:forceChangeToTargetState("none")
end
--Function:检测普通攻击
function clsLivingObject:checkAttack()
	self.timerManager:killTimer()
	local objs = self.oGameWorld:getCurrentLayer():getAreaCanAttackObjs(self,self:getObjectType())
	if table.getn(objs) > 0 then
		for i = 1,#objs do
			if true == self.isLastAttack then
				objs[i]:beAttack(self, lastAttackMoveTime, lastAttackMoveDistance)
			else
				objs[i]:beAttack(self, attackMoveTime, attackMoveDistance)
			end
		end
	end
end
function clsLivingObject:beAttack(srcObj, lastAttackMoveTime, lastAttackMoveDistance)
	self:run("inAir", {srcObject = srcObj, backTime = lastAttackMoveTime, backDistance = lastAttackMoveDistance, hitType = "bruise"})
	--self:doBeAttack(srcObj, lastAttackMoveTime, lastAttackMoveDistance, "bruise")
end
function clsLivingObject:setHpBar()
end
--Function:取得敌人对象数组
function clsLivingObject:getTargets()
	return self.oGameWorld:getCurrentLayer():getTargets(self, self:getObjectType())
end
--Function:转向
function clsLivingObject:turn(x,y)
	local xOrig = self:getPositionX()
	if xOrig < x then
		self:turnRight()
	else
		self:turnLeft()
	end
end
--Function:受伤扣HP
function clsLivingObject:damage(damageNum)
	self.HP = self.HP - damageNum
	if self.HP <= 0 then
		self.HP = 0
	end
	if self and self:getCurState() ~= "dead" then
		self:setHpBar()
	end
end
--Function:被技能击中，播放受伤动画并改变颜色
function clsLivingObject:beSkillAndSetColor(color, duration, skillID)
	self:beSkill(self, skillID, self.oSkillEffectFunc.eForEnemies)
	if color then
		self:setHittedColor(color, duration)
	end
end

--[[
--Function:获取受击范围
function clsLivingObject:getBeAttackRange()
	if self.propertyID then
		local selfPosX, selfPosY = self:getPosition()
		self.horizontalBeAttackRange = CCRectMake(selfPosX + self._root:getContentSize().width/2 - self.oMonsterCfg:getBeAtkRangeX(self.propertyID)/2,
						  selfPosY + self._root:getContentSize().height/2 - self.oMonsterCfg:getBeAtkRangeY(self.propertyID)/2,
						  self.oMonsterCfg:getBeAtkRangeX(self.propertyID),
						  self.oMonsterCfg:getBeAtkRangeY(self.propertyID))
		return self.horizontalBeAttackRange
	end
	self.horizontalBeAttackRange = CCRectMake(0,0,0,0)
	return self.horizontalBeAttackRange
end
--]]

--Function:获取受击范围
function clsLivingObject:getBeAttackRange()
	--self:calHorizontalBeAttackRange()
	return self.horizontalBeAttackRange
end
--Function:计算水平包围盒
function clsLivingObject:calHorizontalBeAttackRange()
	if self.propertyID then
		local selfPosX, selfPosY = self:getPosition()
		self.horizontalBeAttackRange =  CCRectMake(selfPosX - self.oMonsterCfg:getBeAtkRangeX(self.propertyID)/2,
						  selfPosY - self.groundClearance,
						  self.oMonsterCfg:getBeAtkRangeX(self.propertyID),
						  self.oMonsterCfg:getBeAtkRangeY(self.propertyID))
	else
		self.horizontalBeAttackRange = CCRectMake(0,0,0,0)
	end
end

function clsLivingObject:setGroupID(groupID)
	self.groupID = groupID
end

function clsLivingObject:getGroupID()
	return self.groupID
end

--function get/set离地高度
function clsLivingObject:setGroundClearance(groundClearance)
	self.groundClearance = groundClearance
end

function clsLivingObject:getGroundClearance()
	return self.groundClearance
end

--Function:受伤数字特效以及扣除HP
function clsLivingObject:damageEffect(srcObject, minHitNum, maxHitNum)
	local hitNum = math.random(minHitNum,maxHitNum)
	local isCrit = math.random(1,14)
	if isCrit >= 12 then
		hitNum = hitNum * 4
		self.wordNumberEffect:setNumberAndColor(hitNum, "Red", "crit_zn")
	elseif isCrit <= 2 then
		self.wordNumberEffect:runMiss()
		--self:standStrongly()
		return
	else
		self.wordNumberEffect:setNumberAndColor(hitNum, "Orange")
	end
	srcObject:addHitsNum()
	self:damage(hitNum)
end

function clsLivingObject:canPlayBeHittedAction()
	local isCanPlay = true
	if self.HP <= 0 then
		self:run("dead")
		--self:death()
		isCanPlay = false
	end
	if self:getIsUnhurtState() then
		isCanPlay = false
	end
	return isCanPlay
end

--Function:受伤动作
function clsLivingObject:HittedAction(srcObject,backTime,backDistance,hitType)
	local x,y = self:getPosition()
	local new_x = 0
	if srcObject:getDirection() < 0 then
		new_x = math.max(math.abs(self.oGameWorld:getMapLeftLimit()),x - backDistance)
	else
		new_x = math.min(math.abs(self.oGameWorld:getMapRightLimit()),x + backDistance)
	end
	self:doRunAction(backTime,ccp(new_x,y),hitType)
end

--Function:受伤光效
function clsLivingObject:HittedLight()
	--if not self.oObjectFactory then
		self.oObjectFactory = Class("lua/game/clsObjectFactory.lua"):getInstance()
	--end
	local height = self:getBBHeight()
	local lightConfig = {resID = 501, x=0,y = 0.5 * height}
	local effect = self.oObjectFactory:createObject(self,"hiteffect",lightConfig)
end

--Function:是否存活
function clsLivingObject:isLife()
	if self.stateMachine then
		return self.stateMachine:getNowState() ~= "dead"
	end
end
--Function:播放跑动骨骼动画，并移动
function clsLivingObject:doRunAction(time,ptDest,animationName)
	self:play(animationName)
	MOD_ACTION.a_moveTo(self, time, ptDest)
end
--Function:累加连击数
function clsLivingObject:addHitsNum()
	if self == self.oGameWorld:getCameraControlObj() then
		self.hitNum = self.hitNum + 1
		self.oGameWorld:getCurrentLayer():setHitsNum(self.hitNum)
		local function fun()
			self:clearCurHitStat()
		end
		local obj = self.oGameWorld:getCurrentLayer():getWordNumberEffect():getCOObj()
		obj:stopAllActions()
		MOD_ACTION.f_delay_do(obj,fun,nil,2)
	end
end
--Function:清除连击数
function clsLivingObject:clearCurHitStat()
	self.hitNum = 0
	self.oGameWorld:getCurrentLayer():setHitsNum(self.hitNum)
end
--Function:设置霸体状态
function clsLivingObject:setIsUnhurtState(isUnhurtState)
	self.isUnhurtState = isUnhurtState
end
--Function:是否处于霸体状态
function clsLivingObject:getIsUnhurtState()
	return self.isUnhurtState
end
--Function:拿到技能管理器
function clsLivingObject:getSkillActionManager()
	return self.skillActionManager
end
--Function:走动
function clsLivingObject:walk(x, y, peopleCos)
	local function doRun()
		local currentX,currentY = self:getPosition()
		self:setPosition(x,y)
		if peopleCos then
			self:setDirection(peopleCos)
		else
			self:setDirection(x - currentX)
		end
		if self.stateMachine:getNowState() ~= "walk" then
			self:play("run")
		end
	end
	if self.isSkillMoveState then
		doRun()
	else
		self.stateMachine:changeToTargetState("walk", doRun)
	end
end

function getClass()
	return clsLivingObject
end
------------------------------private-----------------------------
------------------------------------------------------------------
function clsLivingObject:init(args)
	self.stateMachine = Class("lua/game/combat/clsStateMachine.lua"):New(self)
	self.timerManager = Class("lua/game/clsObjectTimerManager.lua"):New()             --定时器管理器
	self.skillActionManager = Class("lua/game/clsObjectSkillActionManager.lua"):New() --技能管理器
	self.behavior = Class("lua/game/clsObjBehavior.lua"):New(self)
	--self.objBehavior = Class("lua/game/clsObjBehavior.lua"):New(self)
	self.nowState = "none"
	self.originalAnimate = {} -- 变身前
	self.isLastAttack = false --最后一击
	self.newBody = {} --变身
	self.attackLights = {} --刀光
	self.bruiseLights = {} --受击特效
	self.attackRange = CCRectMake(0,0,0,0)
	self.canDestory = false
	self.isUnhurtState = false
	self.skillActionArray = {}
	self.HP = 0
	local args = {res = "BattleNum", x = self:getBBWidth()/2, y = self:getBBHeight()}
	self.wordNumberEffect = self.oObjectFactory:createObject(self,"wordnumbereffect",args)
	self.checkAttackTimeArray = {} --受击检测时间管理数组,对象销毁时统一删除
	self.hitNum = 0
	self:createName()
	--组ID
	self.groupID = 0
	--对象离地高度
	self.groundClearance = 0
	--包围盒参数
	self.beAttackRangeX = 0
	self.beAttackRangeY = 0
	self.beAttackRangeZ = 0
	--水平包围盒
	self.horizontalBeAttackRange = CCRectMake(0,0,0,0)
	
	self.animateList = {}  --自定义的动作
end

function clsLivingObject:addAnimate(animate)
	table.insert(self.animateList, animate)
end

function clsLivingObject:stopAllAnimate()
	if MOD_UTIL.isTableHasElement( self.animateList ) then
		for k, v in pairs( self.animateList ) do
			v:endAnimate()
			self.animateList[ k ] = nil
		end
	end
end

function clsLivingObject:doBehavior(state, args)
	self.stateMachine:planToRun(state, args)
end

function clsLivingObject:createName()
	local nameHeight = self.oResCfg:getResourcesRealHeightByID(self.resID)
	if not nameHeight or nameHeight == 0 then
		nameHeight = self.oResCfg:getResourcesBoundingBoxYByID(self.resID)
	end
	self.nameLabel = Class("lua/game/clsObjectName.lua"):New(self, {text = self.oResCfg:getResourcesNameByID(self.resID), x = 0, y = nameHeight, z = 10, turnAccordingToParent = false})
	--self.nameLabel = createLabelTTF(self, {text = self.oResCfg:getResourcesNameByID(self.resID), x = 0, y = nameHeight, z = 1000})
	self.nameLabel:enableStroke(0,0,0,2)
end

function clsLivingObject:onDestroy()
	self:stopAllActions()
	self:stopAllAnimate()
	self.timerManager:destroy()
	self.stateMachine = nil
end

--Function:执行死亡
function clsLivingObject:death()
	local function doDeath()
		if self.stateMachine:getNowState() ~= "dead" then
			self.isDying = true
			self._root:stopAllActions()		
			self:deathEffect()
			local scaleX = self:getScaleX()
			self:play("dead")
			self:setScaleX(scaleX)
			self.curAnimate:setColor(ccc3(255, 255, 255))
		end
	end
	self.stateMachine:changeToTargetState("dead", doDeath)
end

function clsLivingObject:deathEffect()
end

function clsLivingObject:isCanDestory()
	return self.canDestory
end

--Input:对象，移动时间，目标点，速度，延迟多久执行，回调
--Function:对边界进行判断，并进行移动
function clsLivingObject:moveTo(obj,moveTime,desPosition, speed,delay,fun,arg)
	local nextX, nextY = self.oGameWorld:fixPosition(desPosition.x,desPosition.y) --边界修正
	if moveTime then
		MOD_ACTION.a_moveTo(obj,moveTime,ccp(nextX,nextY),delay,fun,arg)
	else
		if not speed then
			speed = 280 --移动动作速度，以像素为单位
		end
		MOD_ACTION.a_moveTo(obj,ccpDistance(ccp(self:getPosition()),ccp(nextX,nextY)) / speed, ccp(nextX,nextY),delay,fun,arg)
	end
end

